<?php
/**
 * video.class.php
 * 视频处理类
 */
class video
{
    protected $config = array(
        'trans2mp4'
    );

    /* 文件目录 */
    private $updFilePath = '';

    /* 预定义模型 */
    private $_attachment_content_temp = ''; // 定时临时附件模型
    private $_task_order = ''; // 定时任务模型

    /**
     * 初始化
     */
    public function init ($method)
    {
        /* 设置为忽略与用户的断开（脚本将继续运行） */
        ignore_user_abort(true);

        /* 过滤可执行方法 */
        if (! method_exists($this, $method)) {
            throw new MgException('method ' . $method . ' not exists', 10001);
        }
        if (! in_array($method, $this->config)) {
            throw new MgException('method not allow to access', 10002);
        }

        /* 文件目录 */
        $this->updFilePath = Mg()->config['upload_root_dir'];

        /* 预定义模型 */
        $this->_attachment_content_temp = Mg()->mongo->collection('attachment_content_temp');
        $this->_task_order = Mg()->mongo->collection('task_order');

        /* 执行方法 */
        $this->$method();
    }

    /**
     * 视频处理类 - 转码转封装为 mp4 格式文件
     */
    public function trans2mp4()
    {
        /* 接收参数 */
        $order_id = $_POST['order_id'];
        $filepath = $_POST['filepath'];

        /* 校验参数 */
        if (! file_exists($filepath)) {
            Mg()->log->log(['desc' => '转码出错', 'msg' => $filepath . '，该文件不存在'], 1, 'transcode_error_');
            return false;
        }

        /* 执行 */
        do {
            $result = $this->_trans2mp4($filepath);
            if ($result['status'] == 0) {
                /* sleep3秒，以防止转码过快导致异步冲突重复写表的情况 */
                sleep(3);

                /* 处理地址 */
                $filepath_mp4 = str_replace($this->updFilePath, '/', $result['data']['filepath']);
                $tansinfo = array(
                    'filepath_input' => $filepath,
                    'filepath_output' => $filepath_mp4
                );
                Mg()->log->log(['desc' => '转封装为 mp4', 'tansinfo' => $tansinfo], 0, 'compare_');

                /* 更新信息 */
                $update_attachment = array(
                    'order_id' => $order_id,
                    'status' => 1,
                    'filepath' => $filepath_mp4,
                    'filesize' => filesize($result['data']['filepath']),
                    'hashcode' => md5_file($result['data']['filepath']),
                );
                $this->_attachment_content_temp->update(function($query) use($update_attachment) {
                    $query->where(['order_id' => $update_attachment['order_id']])
                        ->set('status', $update_attachment['status'])
                        ->set('filepath', $update_attachment['filepath'])
                        ->set('filesize', $update_attachment['filesize'])
                        ->set('hashcode', $update_attachment['hashcode']);
                });

                $update_order = array(
                    '_id' => $order_id,
                    'status' => 1
                );
                $this->_task_order->update(function($query) use($update_order) {
                    $query->whereId($update_order['_id'])
                        ->set('status', $update_order['status']);
                });
            }
        } while (
            $result['status'] != 0
        );

        return $result;
    }

    /**
     * 转码转封装为 mp4 格式文件
     *
     * @param string $filepath 视频文件地址
     * @return array
     */
    private function _trans2mp4 ($filepath)
    {
        $res = array('status' => 0, 'msg' => null, 'data' => null);

        /* 处理需要处理的文件地址 */
        $input = str_replace('//', '/', $filepath);

        /* 处理输出路径 */
        $filepath_arr = explode('.', $filepath);
        $filepath_arr[count($filepath_arr) - 1] = 'mp4';
        $filepath_new = implode('.', $filepath_arr);
        $output = str_replace('//', '/', $filepath_new);

        /* 执行 */
        $exec = "ffmpeg -i {$input} -vcodec copy -acodec aac {$output} -y && echo success";
        $result = exec($exec);
        if ($result != 'success') {
            $res['status'] = 1;
            $res['msg'] = '请检查磁盘读写权限';
        } else {
            $res['data']['filepath'] = $filepath_new;
        }

        return $res;
    }
}
